package com.xbongbong.parent.parse.data;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xbongbong.paas.constant.MessageConstant;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.domain.entity.PaasFormExplainEntity;
import com.xbongbong.paas.domain.entity.ext.PaasFormDataEntityExt;
import com.xbongbong.paas.enums.BelongEnum;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.enums.FieldTypeEnum;
import com.xbongbong.paas.field.FieldAttrEntity;
import com.xbongbong.paas.field.ItemPoJo;
import com.xbongbong.paas.field.LinkInfoPojo;
import com.xbongbong.paas.field.LinkedAttrPoJo;
import com.xbongbong.paas.field.MultiUnitItemPoJo;
import com.xbongbong.paas.field.UnitItemPoJo;
import com.xbongbong.paas.help.ProFormHelp;
import com.xbongbong.paas.model.PaasFormExplainModel;
import com.xbongbong.paas.pojo.dto.AnalysisDataDTO;
import com.xbongbong.paas.pojo.vo.LinkResultDataDTO;
import com.xbongbong.paas.pojo.vo.LinkResultDataVO;
import com.xbongbong.paas.service.field.FieldAnalysisHandler;
import com.xbongbong.paas.service.field.FieldAnalysisPoJo;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.Arith;
import com.xbongbong.paas.toolbox.util.BeanUtil;
import com.xbongbong.paas.toolbox.util.CloneUtil;
import com.xbongbong.paas.toolbox.util.CollectionsUtil;
import com.xbongbong.paas.toolbox.util.DateUtil;
import com.xbongbong.paas.toolbox.util.StringUtil;
import com.xbongbong.paas.util.ExplainUtil;
import com.xbongbong.paas.util.ItemUtil;
import com.xbongbong.pro.constant.BusinessConstant;
import com.xbongbong.pro.enums.SaasMarkEnum;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.pro.formdata.pojo.dto.LinkDataDTO;
import com.xbongbong.pro.formdata.pojo.dto.LinkDataInfoDTO;
import com.xbongbong.pro.formexplain.pojo.dto.HandlerExplainDTO;
import com.xbongbong.pro.user.pojo.ReturnUserAndDepartmentPojo;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.constant.MultiUnitConstant;
import com.xbongbong.saas.constant.ProductConstant;
import com.xbongbong.saas.constant.StockConstant;
import com.xbongbong.saas.constant.StringConstant;
import com.xbongbong.saas.domain.entity.WorkOrderExplainEntity;
import com.xbongbong.saas.enums.ProductPrintHelpEnum;
import com.xbongbong.saas.enums.SelectProductEnum;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.enums.business.ProductEnum;
import com.xbongbong.saas.help.RelativeProductHelp;
import com.xbongbong.saas.help.SaasFormHelp;
import com.xbongbong.saas.model.WorkOrderExplainModel;
import com.xbongbong.saas.model.impl.ProductModelImpl;
import com.xbongbong.saas.toolbox.help.FastJsonHelper;
import com.xbongbong.saas.util.SpecificationUtil;
import com.xbongbong.saas.util.UserFieldUtil;
import com.xbongbong.sys.domain.entity.DepartmentEntity;
import com.xbongbong.sys.domain.entity.UserEntity;
import com.xbongbong.sys.model.UserModel;
import org.apache.commons.collections4.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @author: wufeng
 * @date: 2018/12/13 21:32
 * @desrcption: 表单数据关联数据父类
 */

@Component
public class BaseFormDataLinkDataHelp {

    private static final Logger LOG = LoggerFactory.getLogger(BaseFormDataLinkDataHelp.class);

    @Resource
    private FormDataDetailAnalysisDataHelp formDataDetailAnalysisDataHelp;
    @Resource
    private FormDataLinkDataAnalysisDataHelp formDataLinkDataAnalysisDataHelp;
    @Resource
    private FormDataListAnalysisDataHelp formDataListAnalysisDataHelp;
    @Resource
    private ProFormHelp proFormHelp;
    @Resource
    private PaasFormExplainModel paasFormExplainModel;
    @Resource
    private WorkOrderExplainModel workOrderExplainModel;
    @Resource
    private UserModel userModel;
    @Resource
    private LinkDataHelp linkDataHelp;
    @Resource
    private Map<Integer, FieldAnalysisHandler> fieldAnalysisHandlerMap;
    @Resource
    private RelativeProductHelp relativeProductHelp;
    @Resource
    private SaasFormHelp saasFormHelp;

    /**
     * 子表单关联数据渲染主键字段，关联显示字段；编辑界面和打印使用
     * @param fieldAttrEntity
     * @param linkDataDTO
     * @param data
     * @param linkResultDataVO
     * @param formExplainMap
     * @param workOrderFormExplainMap
     * @param formDataMap
     * @return
     * @throws XbbException
     */
    protected JSONArray getSubFormLinkData(FieldAttrEntity fieldAttrEntity, LinkDataDTO linkDataDTO, JSONObject data, LinkResultDataVO linkResultDataVO,Map<String, PaasFormExplainEntity> formExplainMap, Map<String, WorkOrderExplainEntity> workOrderFormExplainMap, Map<String, PaasFormDataEntityExt> formDataMap) throws XbbException {

        Integer businessType = linkDataDTO.getBusinessType();
        String key = fieldAttrEntity.getAttr();
        String corpid = linkDataDTO.getCorpid();
        Map<String, UserEntity> userMap = linkResultDataVO.getUserMap();
        Map<String, DepartmentEntity> departmentMap = linkResultDataVO.getDepartmentMap();
        JSONArray resultList = new JSONArray();
        Set<String> subLinkDataSet = new HashSet<>();
        Map<String, FieldAttrEntity> subExplainMap = new HashMap<>(fieldAttrEntity.getSubForm().getItems().size());
        fieldAttrEntity.getSubForm().getItems().forEach(item->{
            if (Objects.equals(FieldTypeEnum.LINK_DATA.getType(), item.getFieldType()) || Objects.equals(FieldTypeEnum.LINK_DATA_MULTI.getType(), item.getFieldType())) {
                subLinkDataSet.add(item.getAttr());
            }
            subExplainMap.put(item.getAttr(), item);
        });
        if (subLinkDataSet.isEmpty()) {
            return data.getJSONArray(key);
        }
        JSONArray jsonArray = data.getJSONArray(key) == null ? new JSONArray() : data.getJSONArray(key);
        Map<String, Set<Long>> subLinkDataMap = new HashMap<>(jsonArray.size());
        for (int i = 0; i < jsonArray.size(); i++) {
            if (jsonArray.get(i) instanceof Integer) {
                continue;
            }
            JSONObject subJsonObject = jsonArray.getJSONObject(i);
            if (Objects.equals(FieldTypeEnum.SELECT_PRODUCT.getType(), fieldAttrEntity.getFieldType())) {
                subJsonObject.remove(ProductEnum.ENABLE_BATCH_SHELF_LIFE.getSaasAttr());
                subJsonObject.remove(ProductEnum.ENABLE_SERIAL_NUMBER.getSaasAttr());
                subJsonObject.remove(ProductEnum.SHELF_LIFE_DAYS.getSaasAttr());
                subJsonObject.remove(ProductConstant.UNIT_RATE);
                subJsonObject.remove(ProductConstant.TRANSFORM_UNIT_RATE);
                subJsonObject.remove(ProductEnum.ENABLE_MULTI_UNIT.getSaasAttr());
                subJsonObject.remove(ProductConstant.PRICE);
            }

            subLinkDataSet.forEach(item->{
                FieldAttrEntity subFieldAttr = subExplainMap.get(item);
                if (Objects.equals(subFieldAttr.getFieldType(), FieldTypeEnum.LINK_DATA.getType())) {
                    Long id = null;
                    try {
                        id = subJsonObject.getLong(item);
                    } catch (Exception e) {
                        LOG.error("子表单关联数据解析异常", e);
                    }
                    if (id == null || Objects.equals(id, 0L)) {
                        return;
                    }
                    if (subLinkDataMap.containsKey(item)) {
                        Set<Long> list = subLinkDataMap.get(item);
                        list.add(id);
                        subLinkDataMap.put(item, list);
                    } else {
                        Set<Long> list = new HashSet<>();
                        list.add(id);
                        subLinkDataMap.put(item, list);
                    }
                } else {
                    List<Long> idList = null;
                    try {
                        idList = JSON.parseArray(subJsonObject.getString(item), Long.class);
                    } catch (Exception e) {
                        LOG.error("子表单关联多选数据解析异常", e);
                    }
                    if (CollectionsUtil.isNotEmpty(idList)) {
                        if (subLinkDataMap.containsKey(item)) {
                            Set<Long> list = subLinkDataMap.get(item);
                            list.addAll(idList);
                            subLinkDataMap.put(item, list);
                        } else {
                            Set<Long> list = new HashSet<>();
                            list.addAll(idList);
                            subLinkDataMap.put(item, list);
                        }
                    }
                }
            });
        }
        Map<String, JSONObject> json = new HashMap<>(subLinkDataMap.size());
        List<FieldAttrEntity> linkFieldList;
        for (Map.Entry<String, Set<Long>> entry : subLinkDataMap.entrySet()) {
            String attr = entry.getKey();
            Set<Long> idList = entry.getValue();
            FieldAttrEntity subField = subExplainMap.get(attr);
            LinkInfoPojo linkInfoPojo = subField.getLinkInfo();
            Long formId = linkInfoPojo.getLinkFormId();
            // 获取关联表的字段解释信息
            Map<String, FieldAttrEntity> linkExplainMap = new HashMap<>();
            if (Objects.equals(XbbRefTypeEnum.WORK_ORDER.getCode(), linkInfoPojo.getLinkBusinessType())) {
                WorkOrderExplainEntity workOrderExplainEntity = workOrderFormExplainMap.get(formId.toString());
                if (Objects.nonNull(workOrderExplainEntity)) {
                    linkExplainMap = ExplainUtil.getExplainMap(workOrderExplainEntity.getExplains(), null);
                }
            } else if (formExplainMap.containsKey(formId.toString())){
                linkExplainMap = ExplainUtil.getExplainMap(formExplainMap.get(formId.toString()).getExplains(), null);
            }
            if (linkExplainMap.isEmpty()) {
                continue;
            }
            String linkKey = linkInfoPojo.getLinkKey();
            linkFieldList = new ArrayList<>();
            // 主键字段
            FieldAttrEntity linkKeyField = linkExplainMap.get(linkKey);
            if (Objects.nonNull(linkKeyField)) {
                linkFieldList.add(linkKeyField);
            }
            List<LinkedAttrPoJo> linkedShowAttrList = linkInfoPojo.getLinkedShowAttr();
            if (Objects.equals(FieldTypeEnum.SELECT_PRODUCT.getType(), fieldAttrEntity.getFieldType())) {
                for (LinkedAttrPoJo item : linkInfoPojo.getLinkedAttr()) {
                    if (!linkExplainMap.containsKey(item.getAttr())) {
                        continue;
                    }
                    linkFieldList.add(linkExplainMap.get(item.getAttr()));
                }
            }
            if (CollectionUtils.isNotEmpty(linkedShowAttrList)) {
                for (LinkedAttrPoJo item : linkedShowAttrList) {
                    if (!linkExplainMap.containsKey(item.getAttr())) {
                        continue;
                    }
                    linkFieldList.add(linkExplainMap.get(item.getAttr()));
                }
            }
            if (CollectionUtils.isNotEmpty(linkInfoPojo.getLinkedAttr())) {
                for (LinkedAttrPoJo item : linkInfoPojo.getLinkedAttr()) {
                    if (!linkExplainMap.containsKey(item.getAttr()) || ExplainUtil.isSubForm(item.getFieldType())) {
                        // 字段不存在，且关联字段如果是子表单字段不进行解析
                        continue;
                    }
                    linkFieldList.add(linkExplainMap.get(item.getAttr()));
                }
            }

            for (FieldAttrEntity attrEntity : linkFieldList) {
                if (Objects.equals(attrEntity.getSaasAttr(), SelectProductEnum.UNIT.getSaasAttr())) {
                    List<ItemPoJo> productItems = relativeProductHelp.getBusinessUnitItems(corpid);
                    attrEntity.setItems(productItems);
                } else if (Objects.equals(attrEntity.getSaasAttr(), ProductEnum.UNIT.getSaasAttr())) {
                    List<ItemPoJo> productItems = saasFormHelp.getProductItems(corpid);
                    attrEntity.setItems(productItems);
                }
            }
            FieldAnalysisPoJo fieldAnalysisPoJo = new FieldAnalysisPoJo(userMap, departmentMap, linkDataDTO.getMainUserMap(), linkDataDTO.getCoUserMap(), linkInfoPojo.getLinkBusinessType(), true, corpid, linkInfoPojo.getLinkFormId(), linkInfoPojo.getLinkSaasMark(), null);
            StringBuilder stringBuilder;
            for (Long value : idList) {
                String dataKey = String.valueOf(value);
                stringBuilder = new StringBuilder().append(attr).append("_").append(value);
                if (Objects.equals(SaasMarkEnum.SAAS.getCode(), linkInfoPojo.getLinkSaasMark())) {
                    dataKey = linkInfoPojo.getLinkBusinessType() + "_" + value;
                }
                JSONObject jsonObject = new JSONObject();
                PaasFormDataEntityExt paasFormDataEntityExt = formDataMap.get(dataKey);
                JSONObject valueJson = new JSONObject();
                if (Objects.nonNull(paasFormDataEntityExt)) {
                    JSONObject targetData = paasFormDataEntityExt.getData();
                    for (FieldAttrEntity item : linkFieldList) {
                        FieldAnalysisHandler fieldAnalysisHandler = fieldAnalysisHandlerMap.get(item.getFieldType());
                        if (Objects.isNull(fieldAnalysisHandler)) {
                            continue;
                        }
                        Object object = fieldAnalysisHandler.getValue(item, paasFormDataEntityExt,  paasFormDataEntityExt.getData(), fieldAnalysisPoJo);
                        valueJson.put(item.getAttr(), object);
                    }
                    if (Objects.equals(linkInfoPojo.getLinkBusinessType(), XbbRefTypeEnum .PRODUCT.getCode())) {
                        JSONObject productJson = ProductModelImpl.setProductAttribute(targetData);
                        valueJson.putAll(productJson);
                    }
                }
                jsonObject.put("id", value);
                jsonObject.put("dataId", value);
                jsonObject.put("data", valueJson);

                json.put(stringBuilder.toString(), jsonObject);
            }
        }
        for (int i = 0; i < jsonArray.size(); i++) {
            if (jsonArray.get(i) instanceof Integer) {
                continue;
            }
            JSONObject subJsonObject = jsonArray.getJSONObject(i);
            subLinkDataSet.forEach(item->{
                FieldAttrEntity subFieldAttr = subExplainMap.get(item);
                if (Objects.equals(subFieldAttr.getFieldType(), FieldTypeEnum.LINK_DATA.getType())) {
                    if (subJsonObject.get(item) == null || Objects.equals(subJsonObject.get(item), 0L)) {
                        return;
                    }
                    try {
                        JSONObject linkDataJson = json.get(item + "_" + subJsonObject.getLong(item));
                        // 设置关联产品里的产品字段
                        Long refProductId = subJsonObject.getLong(BusinessConstant.REF_PRODUCT_ID);
                        if (Objects.nonNull(linkDataJson)) {
                            JSONObject valueJson = linkDataJson.getJSONObject("data");
                            subJsonObject.put(item, linkDataJson);
                            setSelectProduct(subFieldAttr, subJsonObject, valueJson, linkDataDTO.getGroupBaseUnitMap(), subJsonObject, refProductId, businessType);
                        }
                    } catch (Exception e) {
                        LOG.error("子表单关联数据解析异常", e);
                    }
                } else {
                    // 格式:[234,4545,56767]
                    JSONArray linkDataMultiIdArray = subJsonObject.getJSONArray(item);
                    if (CollectionsUtil.isNotEmpty(linkDataMultiIdArray)) {
                        JSONArray linkDataMulti = new JSONArray();
                        for (int j=0; j<linkDataMultiIdArray.size(); j++) {
                            JSONObject linkDataJson = json.get(item + "_" + linkDataMultiIdArray.getLong(j));
                            if (Objects.nonNull(linkDataJson)) {
                                linkDataMulti.add(linkDataJson);
                            }
                        }
                        subJsonObject.put(item, linkDataMulti);
                    }
                }
            });
            resultList.add(subJsonObject);
        }
        return resultList;
    }

    /**
     * 判断是否是关联数据，如果是的话，进行解析数据拼装，并调用getLinkData进行主键字段，关联字段，关联显示字段的解析
     * @param fieldAttrEntity 关联数据字段
     * @param data 源数据
     * @param resultJsonObject 解析的数据，将放在这个里面
     * @param userMap
     * @param departmentMap
     * @param linkDataDTO
     * @param formExplainMap 非工单的字段解释
     * @param workOrderFormExplainMap
     * @param businessType
     * @param formDataMap
     * @param linkedAttrPoJos
     * @throws XbbException
     */
    protected void setLinkData(FieldAttrEntity fieldAttrEntity, JSONObject data, JSONObject resultJsonObject, Map<String, UserEntity> userMap, Map<String, DepartmentEntity> departmentMap, LinkDataDTO linkDataDTO, Map<String, PaasFormExplainEntity> formExplainMap, Map<String, WorkOrderExplainEntity> workOrderFormExplainMap, Integer businessType, Map<String, PaasFormDataEntityExt> formDataMap , List<LinkedAttrPoJo> linkedAttrPoJos) throws XbbException {
        String key = fieldAttrEntity.getAttr();
        if(FieldTypeEnum.LINK_DATA.getType().equals(fieldAttrEntity.getFieldType()) || Objects.equals(FieldTypeEnum.LINK_DATA_MULTI.getType(), fieldAttrEntity.getFieldType())){
            String value = data.getString(key);
            Long refProductId = data.getLong(BusinessConstant.REF_PRODUCT_ID);
            String sheetNo = data.getString(SelectProductEnum.SOURCE_SOURCE_DOC.getAttr());
            Double sourcePrice = data.getDouble(SelectProductEnum.SOURCE_PRICE.getAttr());
            // 设置主键字段
            linkDataHelp.setLinkKey(fieldAttrEntity);
            LinkDataDTO cloneLinkDataDTO = (LinkDataDTO) CloneUtil.deepClone(linkDataDTO);
            cloneLinkDataDTO.setBusinessType(fieldAttrEntity.getLinkInfo().getLinkBusinessType());
            cloneLinkDataDTO.setSaasMark(fieldAttrEntity.getLinkInfo().getLinkSaasMark());

            JSONArray linkDataValueArray = new JSONArray();
            if(FieldTypeEnum.LINK_DATA.getType().equals(fieldAttrEntity.getFieldType())) {
                linkDataValueArray.add(data.get(key));
            } else {
                linkDataValueArray = FastJsonHelper.parseArray(value);
            }
            JSONArray linkDataResultArray = new JSONArray();
            for (int i=0; i<linkDataValueArray.size(); i++) {
                String linkDataId = linkDataValueArray.getString(i);
                // 获取关联字段
                JSONObject jsonObject = getLinkData(fieldAttrEntity, formDataMap, linkDataId, formExplainMap, workOrderFormExplainMap, userMap, departmentMap, cloneLinkDataDTO, linkedAttrPoJos);
                if (Objects.nonNull(jsonObject)) {
                    JSONObject linkDataJsonObject = new JSONObject();
                    linkDataJsonObject.put("dataId", linkDataValueArray.get(i));
                    // 关联产品用，不知道有没有影响
                    if (Objects.nonNull(refProductId)) {
                        linkDataJsonObject.put("id", refProductId);
                    } else {
                        linkDataJsonObject.put("id", linkDataValueArray.get(i));
                    }
                    if (Objects.nonNull(sheetNo)) {
                        jsonObject.put(SelectProductEnum.SOURCE_SOURCE_DOC.getAttr(), sheetNo);
                    }
                    if (Objects.nonNull(sourcePrice)) {
                        jsonObject.put(SelectProductEnum.SOURCE_PRICE.getAttr(), sourcePrice);
                    }
                    linkDataJsonObject.put("data", jsonObject);
                    // 设置关联产品里的产品字段
                    setSelectProduct(fieldAttrEntity, resultJsonObject, jsonObject, linkDataDTO.getGroupBaseUnitMap(), data, refProductId, businessType);

                    linkDataResultArray.add(linkDataJsonObject);
                }
            }
            if (CollectionsUtil.isEmpty(linkDataResultArray)) {
                resultJsonObject.put(key, null);
            } else {
                if (FieldTypeEnum.LINK_DATA.getType().equals(fieldAttrEntity.getFieldType())) {
                    resultJsonObject.put(key, linkDataResultArray.get(0));
                } else {
                    resultJsonObject.put(key, linkDataResultArray);
                }
            }
            linkDataHelp.removeLinkKey(fieldAttrEntity);
        } else if (!Objects.equals(fieldAttrEntity.getSaasAttr(), SelectProductEnum.UNIT.getSaasAttr())) {
            resultJsonObject.put(key, data.get(key));
        }
    }

    /**
     * 获取关联数据的进行主键字段，关联字段，关联显示字段的解析
     * @param fieldAttrEntity
     * @param formDataMap
     * @param value
     * @param userMap
     * @param departmentMap
     * @return
     */
    public JSONObject getLinkData(FieldAttrEntity fieldAttrEntity, Map<String, PaasFormDataEntityExt> formDataMap, String value, Map<String, PaasFormExplainEntity> formExplainMap,
                                  Map<String, WorkOrderExplainEntity> workOrderFormExplainMap, Map<String, UserEntity> userMap, Map<String, DepartmentEntity> departmentMap, LinkDataDTO linkDataDTO, List<LinkedAttrPoJo> linkShowAttrList) throws XbbException {
        LinkInfoPojo linkInfoPojo = fieldAttrEntity.getLinkInfo();
        if(linkInfoPojo == null || Objects.isNull(linkInfoPojo.getLinkedAttr())){
            return null;
        }
        List<LinkedAttrPoJo> linkedAttrPoJos = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(linkShowAttrList)) {
            linkedAttrPoJos.addAll(linkShowAttrList);
        }
        LinkedAttrPoJo linkKey = new LinkedAttrPoJo();
        // 塞入主键字段
        linkKey.setAttr(fieldAttrEntity.getLinkInfo().getLinkKey());
        linkedAttrPoJos.add(linkKey);
        Map<Long, List<String>> mainUserMap = linkDataDTO.getMainUserMap();
        Map<Long, List<String>> coUserMap = linkDataDTO.getCoUserMap();
        List<String> ownerIds = new ArrayList<>();
        List<String> coUserIds = new ArrayList<>();
        if (Objects.nonNull(mainUserMap)) {
            ownerIds = mainUserMap.get(value);
        }
        if (Objects.nonNull(coUserMap)) {
            coUserIds = coUserMap.get(value);
        }
        if (Objects.equals(SaasMarkEnum.SAAS.getCode(), linkInfoPojo.getLinkSaasMark())) {
           value = linkInfoPojo.getLinkBusinessType() + "_" + value;
       }
        PaasFormDataEntityExt paasFormDataEntityExt = formDataMap.get(value);
        if(paasFormDataEntityExt == null){
            return null;
        }
        Long formId = linkInfoPojo.getLinkFormId();
        if(formId == null){
            return null;
        }
        // 获取关联表的字段解释信息
        PaasFormExplainEntity linkForm = new PaasFormExplainEntity();
        if (Objects.equals(XbbRefTypeEnum.WORK_ORDER.getCode(), linkInfoPojo.getLinkBusinessType())) {
            WorkOrderExplainEntity workOrderExplainEntity = workOrderFormExplainMap.get(formId.toString());
            BeanUtil.copyProperties(workOrderExplainEntity, linkForm);
        } else {
            linkForm = formExplainMap.get(formId.toString());
        }
        if(linkForm == null){
            return null;
        }
        List<FieldAttrEntity> explainList = JSON.parseArray(linkForm.getExplains(), FieldAttrEntity.class);
        Map<String, FieldAttrEntity> linkExplainMap = ExplainUtil.getExplainMapByList(explainList);
        Set<String> userIdSet = UserFieldUtil.getUserIdList(explainList, paasFormDataEntityExt);
        userIdSet.removeIf(item->userMap.containsKey(item));
        if (CollectionUtils.isNotEmpty(userIdSet)) {
           List<UserEntity> list = userModel.getByUserIdIn(linkDataDTO.getCorpid(), userIdSet, false);
           if (CollectionUtils.isNotEmpty(list)) {
               list.forEach(item->userMap.put(item.getUserId(), item));
           }
        }
        JSONObject targetData = paasFormDataEntityExt.getData() == null ? new JSONObject() : paasFormDataEntityExt.getData();

        JSONObject result = new JSONObject();
        AnalysisDataDTO analysisDataDTO = new AnalysisDataDTO();
        BeanUtil.copyProperties(linkDataDTO, analysisDataDTO);
        analysisDataDTO.setUserMap(userMap);
        analysisDataDTO.setDepartmentMap(departmentMap);
        Map<String, Object> linkDataMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        Set<Object> linkDataSet = new HashSet<>();
        HandlerExplainDTO handlerExplainDTO = new HandlerExplainDTO();
        BeanUtil.copyProperties(linkDataDTO, handlerExplainDTO);
        handlerExplainDTO.setCreatorId(paasFormDataEntityExt.getCreatorId());
        handlerExplainDTO.setOwnerId(ownerIds);
        handlerExplainDTO.setCoUserId(coUserIds);
        // 解析关联数据的显示字段
        String serialNo = "";
        for(LinkedAttrPoJo linkedAttrPoJo: linkedAttrPoJos){
            analysisDataDTO.setDataJsonObject(targetData);
            String attr = linkedAttrPoJo.getAttr();
            FieldAttrEntity linkAttr = linkExplainMap.get(attr);
            if(Objects.isNull(linkAttr)){
                continue;
            }
            if (ExplainUtil.isFieldNeedHide(linkAttr, handlerExplainDTO)) {
                continue;
            }
            if(linkAttr.getVisible().equals(1)){
                if (ExplainUtil.isSubForm(linkAttr.getFieldType())) {
                    Map<String, FieldAttrEntity> subExplainMap = ExplainUtil.getExplainMapByList(linkAttr.getSubForm().getItems());
                    JSONArray jsonArray = targetData.getJSONArray(linkAttr.getAttr());
                    if (Objects.nonNull(jsonArray)) {
                        List<Map<String, Object>> subLinkDataList = new ArrayList<>();
                        for (int i = 0; i < jsonArray.size(); i++) {
                            JSONObject subJson = jsonArray.getJSONObject(i);
                            Iterator subIterator = subJson.keySet().iterator();
                            JSONObject subResult = new JSONObject();
                            Map<String, Object> subLinkData = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                            while (subIterator.hasNext()){
                                String subKey = subIterator.next().toString();
                                FieldAttrEntity subFieldAttrEntity = subExplainMap.get(subKey);
                                if(subFieldAttrEntity == null){
                                    continue;
                                }
                                analysisDataDTO.setAttr(subKey);
                                analysisDataDTO.setFieldAttrEntity(subFieldAttrEntity);
                                analysisDataDTO.setDataJsonObject(subJson);
                                analysisDataDTO.setFormId(paasFormDataEntityExt.getFormId());
                                // TODO
                                formDataDetailAnalysisDataHelp.analysisData(analysisDataDTO, subResult, subLinkData, linkDataSet);
                            }
                            subLinkDataList.add(subLinkData);
                            jsonArray.set(i, subResult);
                        }
                        linkDataMap.put(attr, subLinkDataList);
                    }
                    result.put(attr, jsonArray);
                } else if (Objects.equals(FieldTypeEnum.SERIALNO.getType(), linkAttr.getFieldType())) {
                    // 编号
                    serialNo = paasFormDataEntityExt.getSerialNo();
                    result.put(attr, serialNo);
                } else {
                    if (Objects.equals(linkInfoPojo.getLinkSaasMark(), SaasMarkEnum.SAAS.getCode())) {
                        linkAttr.setItems(proFormHelp.getItem(linkAttr, linkInfoPojo.getLinkBusinessType(), linkForm.getCorpid(), linkForm.getFormId()));
                    }
                    analysisDataDTO.setFieldAttrEntity(linkAttr);
                    analysisDataDTO.setAttr(attr);
                    analysisDataDTO.setFormId(linkForm.getFormId());
                    analysisDataDTO.setDataId(paasFormDataEntityExt.getId());
                    //主键字段按原格式返回
                    if (Objects.equals(fieldAttrEntity.getLinkInfo().getLinkKey(), attr)){
                        formDataLinkDataAnalysisDataHelp.analysisData(analysisDataDTO, result, linkDataMap, linkDataSet);
                    }else {
                        formDataDetailAnalysisDataHelp.analysisData(analysisDataDTO, result, linkDataMap, linkDataSet);
                    }
                    SpecificationUtil.getProductName(linkInfoPojo.getLinkBusinessType(), attr, targetData, result);
                }
            }
        }
        JSONObject linkData = new JSONObject();
        // 将解析完的数据进行拼装
        if (!result.isEmpty()) {
            LinkDataInfoDTO linkDataInfoDTO = new LinkDataInfoDTO();
            BeanUtil.copyProperties(linkDataDTO, linkDataInfoDTO);
            linkDataInfoDTO.setExplainList(explainList);
            linkDataInfoDTO.setData(result);
            linkDataInfoDTO.setSerialNo(serialNo);
            linkDataInfoDTO.setLinkDataSet(linkDataSet);
            linkDataInfoDTO.setLinkDataMap(linkDataMap);
            linkDataInfoDTO.setUserMap(userMap);
            linkDataInfoDTO.setDepartmentMap(departmentMap);
            linkDataInfoDTO.setExplainMap(linkExplainMap);
            linkData = getLinkDataInfo(linkDataInfoDTO);
        }
        if (Objects.equals(linkInfoPojo.getLinkBusinessType(), XbbRefTypeEnum .PRODUCT.getCode())) {
            linkData.put(ProductEnum.ENABLE_BATCH_SHELF_LIFE.getSaasAttr(), targetData.get(ProductEnum.ENABLE_BATCH_SHELF_LIFE.getAttr()));
            linkData.put(ProductEnum.ENABLE_SERIAL_NUMBER.getSaasAttr(), targetData.get(ProductEnum.ENABLE_SERIAL_NUMBER.getAttr()));
            Integer enableShelfLife = StringUtil.isEmpty(targetData.getString(ProductEnum.SHELF_LIFE_DAYS.getAttr())) ? 0 : 1;
            linkData.put(ProductEnum.SHELF_LIFE_DAYS.getSaasAttr(), enableShelfLife);
            linkData.put(ProductEnum.ENABLE_MULTI_UNIT.getSaasAttr(), Objects.isNull(targetData.getLong(ProductEnum.ENABLE_MULTI_UNIT.getAttr())) ? 0: targetData.getLong(ProductEnum.ENABLE_MULTI_UNIT.getAttr()));
            linkData.put(ProductEnum.UNIT.getSaasAttr(), targetData.get(ProductEnum.UNIT.getAttr()));
        }
        return linkData;
    }

    /**
     * 解析日期
     * @param result
     * @param attr
     * @param fieldAttrEntity
     */
    private void getDate(JSONObject result, String attr, FieldAttrEntity fieldAttrEntity){
        if(fieldAttrEntity.getFieldType().equals(FieldTypeEnum.DATETIME.getType())){
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat(fieldAttrEntity.getDateType());
            Date date = new Date(result.getLong(attr)*1000L);
            result.put(attr, DateUtil.getString(date, simpleDateFormat));
        }
    }

    /**
     * 获取主键字段的值
     * @param fieldAttrEntity
     * @param formDataMap
     * @param formExplainMap
     * @param value 关联单选的value是个数值，关联多选的value是个数组
     * @param userMap
     * @param departmentMap
     * @return
     * @throws XbbException
     */
    public Object getPrimaryKeyField(LinkResultDataDTO linkResultDataDTO, FieldAttrEntity fieldAttrEntity, Map<String, PaasFormDataEntityExt> formDataMap,
                                     Map<String, PaasFormExplainEntity> formExplainMap, Map<String, WorkOrderExplainEntity> workOrderExplainMap,
                                     Object value, Map<String, UserEntity> userMap, Map<String, DepartmentEntity> departmentMap) throws XbbException{
        LinkInfoPojo linkInfoPojo = fieldAttrEntity.getLinkInfo();
        if(linkInfoPojo == null || linkInfoPojo.getLinkKey() == null){
            return null;
        }
        String linkKey = linkInfoPojo.getLinkKey();
        Long formId = linkInfoPojo.getLinkFormId();
        if(formId == null){
            return null;
        }
        PaasFormExplainEntity linkForm = new PaasFormExplainEntity();
        if (Objects.equals(XbbRefTypeEnum.WORK_ORDER.getCode(), linkInfoPojo.getLinkBusinessType())) {
            WorkOrderExplainEntity workOrderExplainEntity = workOrderExplainMap.get(formId.toString());
            if (Objects.isNull(workOrderExplainEntity)) {
                return null;
            }
            BeanUtil.copyProperties(workOrderExplainEntity, linkForm);
        } else {
            linkForm = formExplainMap.get(formId.toString());
        }
        if(linkForm == null){
            return null;
        }
        Map<String, FieldAttrEntity> linkExplainMap = ExplainUtil.getExplainMap(linkForm.getExplains(), linkKey);
        FieldAttrEntity linkAttr = linkExplainMap.get(linkKey);
        if(linkAttr == null){
            return null;
        }

        JSONArray linkDataValueArray = new JSONArray();
        if (Objects.equals(FieldTypeEnum.LINK_DATA.getType(), fieldAttrEntity.getFieldType()) && value instanceof Number) {
            linkDataValueArray.add(value);
        } else if (Objects.equals(FieldTypeEnum.LINK_DATA_MULTI.getType(), fieldAttrEntity.getFieldType())) {
            linkDataValueArray = FastJsonHelper.parseArray(JSON.toJSONString(value));
        }
        JSONArray linkDataResultArray = new JSONArray();
        for (int i=0; i<linkDataValueArray.size(); i++) {
            Long linkDataId;
            try {
                linkDataId = linkDataValueArray.getLong(i);
            } catch (Exception e) {
                LOG.error("关联数据解析的时候出错", e);
                continue;
            }
            String key = linkDataValueArray.getString(i);
            Integer saasMark = linkInfoPojo.getLinkSaasMark();
            Integer businessType = linkInfoPojo.getLinkBusinessType();
            if (Objects.equals(saasMark, SaasMarkEnum.SAAS.getCode())) {
                key = linkInfoPojo.getLinkBusinessType() + "_" + key;
            }
            PaasFormDataEntityExt paasFormDataEntityExt = formDataMap.get(key);
            if (paasFormDataEntityExt == null) {
                continue;
            }
            JSONObject targetData = paasFormDataEntityExt.getData() == null ? new JSONObject() : paasFormDataEntityExt.getData();

            JSONObject result = new JSONObject();
            AnalysisDataDTO analysisDataDTO = new AnalysisDataDTO();
            BeanUtil.copyProperties(linkResultDataDTO, analysisDataDTO);
            analysisDataDTO.setUserMap(userMap);
            analysisDataDTO.setDepartmentMap(departmentMap);
            analysisDataDTO.setDataJsonObject(targetData);
            analysisDataDTO.setAttr(linkKey);
            analysisDataDTO.setFormId(formId);
            analysisDataDTO.setBusinessType(businessType);
            analysisDataDTO.setSaasMark(saasMark);
            //  这里暂时不加高级可见的判断
            if (linkAttr.getVisible().equals(1)) {
                analysisDataDTO.setFieldAttrEntity(linkAttr);

                JSONObject jsonObject = new JSONObject();
                jsonObject.put(StringConstant.SAAS_LINK_BUSINESS_ID, linkDataId);
                jsonObject.put(StringConstant.SAAS_LINK_BUSINESS_LINK_TYPE, linkInfoPojo.getLinkBusinessType());
                jsonObject.put("saasMark", linkInfoPojo.getLinkSaasMark());
                if (Objects.equals(FieldTypeEnum.SERIALNO.getType(), linkAttr.getFieldType())) {
                    jsonObject.put("name", paasFormDataEntityExt.getSerialNo());
                    linkDataResultArray.add(jsonObject);
                    continue;
                } else {
                    Map<String, Object> linkData = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                    Set<Object> linkDataSet = new HashSet<>();
                    analysisDataDTO.setIsProcess(true);
                    formDataLinkDataAnalysisDataHelp.analysisData(analysisDataDTO, result, linkData, linkDataSet);
                    SpecificationUtil.getProductName(linkInfoPojo.getLinkBusinessType(), linkKey, targetData, result);
                }
                getDate(result, linkKey, linkAttr);
                jsonObject.put("name", result.get(linkKey));
                linkDataResultArray.add(jsonObject);
            }
        }
        if (CollectionsUtil.isEmpty(linkDataResultArray)) {
            return null;
        }
        return linkDataResultArray;
    }

    public Map<String, PaasFormExplainEntity> getExplainMapByFormIdList(List<Long> formIdList, String corpid) throws XbbException {
        Map<String, PaasFormExplainEntity> formExplainMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        if (!formIdList.isEmpty()) {
            Map<String, Object> explainParam = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            explainParam.put("formIdIn", formIdList);
            explainParam.put(StringConstant.CORPID, corpid);
            explainParam.put(StringConstant.DEL, DelEnum.NORMAL.getDel());
            List<PaasFormExplainEntity> formExplainList = paasFormExplainModel.list(explainParam);
            if(formExplainList == null){
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_EXPLAIN_NOT_EXIST);
            }
            formExplainList.forEach((item)->{
                formExplainMap.put(item.getFormId().toString(), item);
            });
        }
        return formExplainMap;
    }

    public Map<String, WorkOrderExplainEntity> getWorkOrderExplainMapByFormId(List<Long> workOrderFormIdList, String corpid) throws XbbException {
        Map<String, WorkOrderExplainEntity> workOrderFormExplainMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        if (!workOrderFormIdList.isEmpty()) {
            Map<String, Object> explainParam = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            explainParam.put("formIdIn", workOrderFormIdList);
            explainParam.put(StringConstant.CORPID, corpid);
            explainParam.put(StringConstant.DEL, DelEnum.NORMAL.getDel());
            List<WorkOrderExplainEntity> workOrderExplainList = workOrderExplainModel.list(explainParam);
            if(workOrderExplainList == null){
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_EXPLAIN_NOT_EXIST);
            }
            workOrderExplainList.forEach(item->{
                workOrderFormExplainMap.put(item.getFormId().toString(), item);
            });
        }
        return workOrderFormExplainMap;
    }


    public void setLinkDataShowKey(JSONObject resultJsonObject, LinkResultDataDTO linkResultDataDTO, FieldAttrEntity fieldAttrEntity, Map<String,PaasFormDataEntityExt> formDataMap, Map<String,PaasFormExplainEntity> formExplainMap, Map<String,WorkOrderExplainEntity> workOrderFormExplainMap, String value, Map<String,UserEntity> userMap, Map<String,DepartmentEntity> departmentMap) throws XbbException {
        LinkInfoPojo linkInfoPojo = fieldAttrEntity.getLinkInfo();
        if(linkInfoPojo == null || linkInfoPojo.getLinkKey() == null){
            return;
        }
        String linkKey = linkInfoPojo.getLinkKey();
        List<LinkedAttrPoJo> linkedShowAttr = linkInfoPojo.getLinkedShowAttr();

        if (Objects.isNull(linkedShowAttr)){
           // linkedShowAttr = new ArrayList<>(linkInfoPojo.getLinkedAttr());
            linkedShowAttr = new ArrayList<>();
        } else if (Objects.equals(linkInfoPojo.getLinkBusinessType(), XbbRefTypeEnum.PRODUCT.getCode())) {
            LinkedAttrPoJo linkedAttrPoJo = new LinkedAttrPoJo();
            linkedAttrPoJo.setAttr(ProductPrintHelpEnum.PICTURE.getNewAttr());
            linkedAttrPoJo.setAttrName(ProductPrintHelpEnum.PICTURE.getAttrName());
            linkedAttrPoJo.setFieldType(FieldTypeEnum.IMAGE.getType());
            linkedAttrPoJo.setVisible(1);
            linkedShowAttr.add(linkedAttrPoJo);
        }
        Long formId = linkInfoPojo.getLinkFormId();
        if(formId == null){
            return;
        }
        PaasFormExplainEntity linkForm = new PaasFormExplainEntity();
        if (Objects.equals(XbbRefTypeEnum.WORK_ORDER.getCode(), linkInfoPojo.getLinkBusinessType())) {
            WorkOrderExplainEntity workOrderExplainEntity = workOrderFormExplainMap.get(formId.toString());
            BeanUtil.copyProperties(workOrderExplainEntity, linkForm);
        } else {
            linkForm = formExplainMap.get(formId.toString());
        }
        if(linkForm == null){
            return;
        }
        Map<String, FieldAttrEntity> linkExplainMap = ExplainUtil.getExplainMap(linkForm.getExplains(), null);
        FieldAttrEntity linkAttr = linkExplainMap.get(linkKey);
        if(linkAttr == null){
            return;
        }
        String key = value;
        Integer saasMark = linkInfoPojo.getLinkSaasMark();
        if (Objects.equals(saasMark, SaasMarkEnum.SAAS.getCode())) {
            key = linkInfoPojo.getLinkBusinessType() + "_" +key;
        }
        PaasFormDataEntityExt paasFormDataEntityExt = formDataMap.get(key);
        if(paasFormDataEntityExt == null){
            if (Objects.equals(XbbRefTypeEnum.PRODUCT.getCode(),linkInfoPojo.getLinkBusinessType()) && Objects.equals(fieldAttrEntity.getIsRedundant(), 0)){
                Map<String, String> unitMap = linkResultDataDTO.getUnitMap() == null ? new HashMap<>(1 << 1) : linkResultDataDTO.getUnitMap();
                String businessUnit = resultJsonObject.getString(SelectProductEnum.UNIT.getAttr());
                resultJsonObject.put(SelectProductEnum.UNIT.getAttr(), unitMap.getOrDefault(businessUnit, ""));
            }
            return;
        }
        JSONObject targetData = paasFormDataEntityExt.getData();
        if(targetData == null){
            return;
        }
        JSONObject result = new JSONObject();
        AnalysisDataDTO analysisDataDTO = new AnalysisDataDTO();
        BeanUtil.copyProperties(linkResultDataDTO, analysisDataDTO);
        analysisDataDTO.setUserMap(userMap);
        analysisDataDTO.setDepartmentMap(departmentMap);
        analysisDataDTO.setDataJsonObject(targetData);
        analysisDataDTO.setAttr(linkKey);
        if(linkAttr.getVisible().equals(1)){
            analysisDataDTO.setFieldAttrEntity(linkAttr);
            JSONArray jsonArray = new JSONArray();
            JSONObject jsonObject = new JSONObject();
            jsonObject.put(StringConstant.SAAS_LINK_BUSINESS_ID, Long.valueOf(value));
            jsonObject.put(StringConstant.SAAS_LINK_BUSINESS_LINK_TYPE, linkInfoPojo.getLinkBusinessType());
            jsonObject.put("saasMark", linkInfoPojo.getLinkSaasMark());
            if (Objects.equals(FieldTypeEnum.SERIALNO.getType(), linkAttr.getFieldType())){
                jsonObject.put("name", paasFormDataEntityExt.getSerialNo());
                jsonArray.add(jsonObject);
                resultJsonObject.put(fieldAttrEntity.getAttr(), jsonArray);
            } else {
                formDataListAnalysisDataHelp.analysisData(analysisDataDTO, result,null, null);
                getDate(result, linkKey, linkAttr);
                jsonObject.put("name", result.get(linkKey));
                jsonArray.add(jsonObject);
                resultJsonObject.put(fieldAttrEntity.getAttr(), jsonArray);
            }
        }
        //关联数据如果是产品 就将是否开启批次号 和序列号标识添加到参数里面
        if (Objects.equals(XbbRefTypeEnum.PRODUCT.getCode(),linkInfoPojo.getLinkBusinessType()) && Objects.equals(fieldAttrEntity.getIsRedundant(), 0)){
            resultJsonObject.put(ProductEnum.ENABLE_BATCH_SHELF_LIFE.getSaasAttr(), targetData.get(ProductEnum.ENABLE_BATCH_SHELF_LIFE.getAttr()));
            resultJsonObject.put(ProductEnum.ENABLE_SERIAL_NUMBER.getSaasAttr(), targetData.get(ProductEnum.ENABLE_SERIAL_NUMBER.getAttr()));
            resultJsonObject.put(ProductEnum.SHELF_LIFE_DAYS.getSaasAttr(), StringUtil.isEmpty(targetData.getString(ProductEnum.SHELF_LIFE_DAYS.getAttr())) ?  0 : 1);
            Map<String, String> unitMap = linkResultDataDTO.getUnitMap() == null ? new HashMap<>(1 << 1) : linkResultDataDTO.getUnitMap();
            String businessUnit = resultJsonObject.getString(SelectProductEnum.UNIT.getAttr());
            if (BasicConstant.ONE.equals(targetData.getIntValue(ProductEnum.ENABLE_MULTI_UNIT.getAttr()))) {
                resultJsonObject.put(ProductEnum.ENABLE_MULTI_UNIT.getSaasAttr(), 1);
                Long unitVal = targetData.getLong(ProductEnum.UNIT.getAttr());
                Map<Long, MultiUnitItemPoJo> groupBaseUnitMap = linkResultDataDTO.getGroupBaseUnitMap() == null ? new HashMap<>(1 << 1) : linkResultDataDTO.getGroupBaseUnitMap();
                MultiUnitItemPoJo multiUnitItemPoJo = groupBaseUnitMap.getOrDefault(unitVal, new MultiUnitItemPoJo());
                List<UnitItemPoJo> unitItemPoJos = multiUnitItemPoJo.getItemDataPoJoList();
                if (Objects.equals(businessUnit, StringConstant.INVISIBLE_VALUE)) {
                    resultJsonObject.put(SelectProductEnum.UNIT.getAttr(), null);
                } else{
                    resultJsonObject.put(ProductConstant.UNIT_RATE, unitItemPoJos);
                    resultJsonObject.put(ProductConstant.TRANSFORM_UNIT_RATE, unitItemPoJos);
                    if (!StringUtil.isDigital(businessUnit) || Long.parseLong(businessUnit) < ProductConstant.MAX_SINGLE_UNIT_VALUE) {
                        resultJsonObject.put(SelectProductEnum.UNIT.getAttr(), multiUnitItemPoJo.getBaseName());
                    } else {
                        resultJsonObject.put(SelectProductEnum.UNIT.getAttr(), unitMap.get(businessUnit));
                    }
                }
            } else {
                if (Objects.equals(businessUnit, StringConstant.INVISIBLE_VALUE)) {
                    resultJsonObject.put(SelectProductEnum.UNIT.getAttr(), null);
                } else if (Objects.nonNull(resultJsonObject.get(SelectProductEnum.UNIT.getAttr())) && (!StringUtil.isDigital(businessUnit) && !ItemUtil.isUUID(businessUnit))) {
                    resultJsonObject.put(SelectProductEnum.UNIT.getAttr(), businessUnit);
                } else {
                    resultJsonObject.put(SelectProductEnum.UNIT.getAttr(), unitMap.get(businessUnit));
                }
            }
        }
        JSONObject showObj;
        for (LinkedAttrPoJo linkedAttrPoJo : linkedShowAttr) {
            showObj = new JSONObject();
            String attr = linkedAttrPoJo.getAttr().split(StringConstant.COMMA)[1];
            analysisDataDTO.setAttr(attr);
            FieldAttrEntity linkField = linkExplainMap.get(attr);
            if (linkField == null) {
                return;
            }
            if(linkField.getVisible().equals(1)){
                analysisDataDTO.setFieldAttrEntity(linkField);
                if (Objects.equals(FieldTypeEnum.SERIALNO.getType(), linkedAttrPoJo.getFieldType())){
                    HandlerExplainDTO handlerExplainDTO = new HandlerExplainDTO();
                    BeanUtil.copyProperties(analysisDataDTO, handlerExplainDTO);
                    if (!ExplainUtil.isFieldNeedHide(linkField, handlerExplainDTO)) {
                        resultJsonObject.put(linkedAttrPoJo.getAttr(), paasFormDataEntityExt.getSerialNo());
                    }
                } else {
                    formDataListAnalysisDataHelp.analysisData(analysisDataDTO, showObj,null, null);
                    getDate(showObj, attr, linkField);
                    resultJsonObject.put(linkedAttrPoJo.getAttr(),  showObj.get(attr));
                }
            }
        }
    }

    /**
     * 为关联数据和关联查询拼装单行数据
     *
     * @param linkDataInfoDTO 数据封装
     * @return
     */
    public JSONObject getLinkDataInfo(LinkDataInfoDTO linkDataInfoDTO) throws XbbException {

        JSONObject linkDataInfo = new JSONObject();
        try {
            JSONObject data = linkDataInfoDTO.getData();

            // 开始关联数据里关联数据进行解析
            Map<String, FieldAttrEntity> explainMap = linkDataInfoDTO.getExplainMap();

            Iterator<String> iterator = data.keySet().iterator();
            while (iterator.hasNext()) {
                String key = iterator.next();
                if (!explainMap.containsKey(key)) {
                    continue;
                }
                FieldAttrEntity fieldAttrEntity = explainMap.get(key);
                Integer fieldType = fieldAttrEntity.getFieldType();
                FieldTypeEnum fieldTypeEnum = FieldTypeEnum.getFieldTypeEnum(fieldType);
                // 过滤为空的数据
                Boolean isEmpty = (Objects.isNull(data.get(key)))
                        && !Objects.equals(fieldTypeEnum.getBelong(), BelongEnum.SYSTEM.getAlias());
                if (isEmpty) {
                    continue;
                }
                if (ExplainUtil.isSubForm(fieldType)) {
                    if (Objects.isNull(fieldAttrEntity.getSubForm())) {
                        continue;
                    }
                    List<FieldAttrEntity> subFieldList = (List<FieldAttrEntity>) fieldAttrEntity.getSubForm().getItems();
                    if (CollectionsUtil.isEmpty(subFieldList)) {
                        continue;
                    }
                    Map<String, FieldAttrEntity> subExplainMap = ExplainUtil.getExplainMapByList(subFieldList);
                    JSONArray jsonArray = data.getJSONArray(key);
                    for (int i = 0; i < jsonArray.size(); i++) {
                        JSONObject jsonObject = jsonArray.getJSONObject(i);
                        LinkDataInfoDTO dataInfoDTO = new LinkDataInfoDTO();
                        BeanUtil.copyProperties(linkDataInfoDTO, dataInfoDTO);
                        dataInfoDTO.setExplainList(subFieldList);
                        dataInfoDTO.setData(jsonObject);
                        dataInfoDTO.setExplainMap(subExplainMap);
                        jsonArray.set(i, getLinkDataInfo(dataInfoDTO));
                    }
                    linkDataInfo.put(key, jsonArray);
                } else if (FieldTypeEnum.USER_GROUP.getType().equals(fieldType)
                        || FieldTypeEnum.DEPT_GROUP.getType().equals(fieldType)) {
                    List<ReturnUserAndDepartmentPojo> result = data.getJSONArray(key).toJavaList(ReturnUserAndDepartmentPojo.class);
                    linkDataInfo.put(key, result);
                } else if (FieldTypeEnum.USER.getType().equals(fieldType) || FieldTypeEnum.DEPT.getType().equals(fieldType)) {
                    if (( data.get(key) instanceof ReturnUserAndDepartmentPojo) || data.get(key) instanceof Map) {
                        ReturnUserAndDepartmentPojo returnUserAndDepartmentPojo = JSON.parseObject(JSON.toJSONString(data.get(key)), ReturnUserAndDepartmentPojo.class);
                        linkDataInfo.put(key, returnUserAndDepartmentPojo);
                    }

                } else if((FieldTypeEnum.RADIO_GROUP.getType().equals(fieldType)
                        || FieldTypeEnum.COMBO.getType().equals(fieldType))) {
                    // 前面的方法已经解析了
                    linkDataInfo.put(key, data.get(key));
                } else if((FieldTypeEnum.CHECKBOX_GROUP.getType().equals(fieldType)
                        || FieldTypeEnum.COMBO_CHECK.getType().equals(fieldType))) {
                    // 前面的方法已经解析了
                    linkDataInfo.put(key, data.get(key));
                } else if(FieldTypeEnum.ADDRESS.getType().equals(fieldType)) {
                    if (data.get(key) instanceof JSONObject) {
                        linkDataInfo.put(key, data.getJSONObject(key));
                    } else {
                        linkDataInfo.put(key, data.get(key));
                    }
                } else if (FieldTypeEnum.SERIALNO.getType().equals(fieldType)) {
                    linkDataInfo.put(key, linkDataInfoDTO.getSerialNo());
                }else if (FieldTypeEnum.LINK_DATA.getType().equals(fieldType)) {
                } else {
                    linkDataInfo.put(key, data.get(key));
                }

            }

        } catch (Exception e) {
            LOG.error("formDataService.getLinkDataInfo执行出错：", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }

        return linkDataInfo;
    }

    /**
     * 设置关联产品值，序列号，多单位等
     * @param fieldAttrEntity
     * @param resultJsonObject
     * @param jsonObject
     * @param data
     * @param refProductId
     * @param businessType
     */
    protected void setSelectProduct(FieldAttrEntity fieldAttrEntity, JSONObject resultJsonObject, JSONObject jsonObject, Map<Long, MultiUnitItemPoJo> groupBaseUnitMap, JSONObject data, Long refProductId, Integer businessType) {
        if (Objects.equals(fieldAttrEntity.getLinkInfo().getLinkBusinessType(), XbbRefTypeEnum.PRODUCT.getCode()) && Objects.equals(fieldAttrEntity.getAttr(), SelectProductEnum.PRODUCT.getAttr()) && Objects.equals(fieldAttrEntity.getIsRedundant(), 0)) {
            resultJsonObject.put(ProductEnum.ENABLE_BATCH_SHELF_LIFE.getSaasAttr(), jsonObject.get(ProductEnum.ENABLE_BATCH_SHELF_LIFE.getSaasAttr()));
            resultJsonObject.put(ProductEnum.SHELF_LIFE_DAYS.getSaasAttr(), jsonObject.get(ProductEnum.SHELF_LIFE_DAYS.getSaasAttr()));
            resultJsonObject.put(ProductEnum.ENABLE_SERIAL_NUMBER.getSaasAttr(), jsonObject.get(ProductEnum.ENABLE_SERIAL_NUMBER.getSaasAttr()));
            resultJsonObject.put(ProductEnum.ENABLE_MULTI_UNIT.getSaasAttr(), 0);
            if (Objects.equals(jsonObject.getInteger(ProductEnum.ENABLE_MULTI_UNIT.getSaasAttr()), 1)) {
                MultiUnitItemPoJo groupMessage = groupBaseUnitMap.get(jsonObject.getLong(ProductEnum.UNIT.getSaasAttr()));
                if (Objects.isNull(groupMessage)) {
                    return;
                }
                List<UnitItemPoJo> unitItemPoJos = groupMessage.getItemDataPoJoList();
                Map<Long, UnitItemPoJo> unitItemPoJoMap = unitItemPoJos.stream().collect(Collectors.toMap(UnitItemPoJo::getValue, unitItemPoJo -> unitItemPoJo));
                JSONObject unitObj = new JSONObject();
                Double rate = 1D;
                if (data.get(SelectProductEnum.UNIT.getAttr()) instanceof Map) {
                    unitObj = data.getJSONObject(SelectProductEnum.UNIT.getAttr());
                    if (!StringUtil.isDigital(unitObj.getString(MultiUnitConstant.VALUE)) || unitObj.getLong(MultiUnitConstant.VALUE) < ProductConstant.MAX_SINGLE_UNIT_VALUE) {
                        unitObj.put(MultiUnitConstant.MULTI_UNIT_TEXT, groupMessage.getBaseName());
                        unitObj.put(MultiUnitConstant.VALUE, groupMessage.getBaseValue());
                    }
                    Long unitValue = unitObj.getLong(MultiUnitConstant.VALUE);
                    UnitItemPoJo unitItemPoJo = unitItemPoJoMap.getOrDefault(unitValue, new UnitItemPoJo());
                    unitObj.put(MultiUnitConstant.MULTI_UNIT_TEXT, unitItemPoJo.getText());
                    rate = unitItemPoJo.getRate();
                    resultJsonObject.put(SelectProductEnum.UNIT.getAttr(), unitObj);
                } else if (data.get(SelectProductEnum.UNIT.getAttr()) instanceof Long) {
                    unitObj = new JSONObject();
                    Long unitValue = data.getLong(SelectProductEnum.UNIT.getAttr());
                    UnitItemPoJo unitItemPoJo = unitItemPoJoMap.getOrDefault(unitValue, new UnitItemPoJo());
                    unitObj.put(MultiUnitConstant.MULTI_UNIT_TEXT, unitItemPoJo.getText());
                    unitObj.put(MultiUnitConstant.VALUE, unitItemPoJo.getValue());
                    rate = unitItemPoJo.getRate();
                    resultJsonObject.put(SelectProductEnum.UNIT.getAttr(), unitObj);
                } else if (data.get(SelectProductEnum.UNIT.getAttr()) instanceof String || Objects.isNull(data.get(SelectProductEnum.UNIT.getAttr()))) {
                    unitObj = new JSONObject();
                    String unit = data.getString(SelectProductEnum.UNIT.getAttr());
                    if (!StringUtil.isDigital(unit) || Long.parseLong(unit) < ProductConstant.MAX_SINGLE_UNIT_VALUE) {
                        unitObj.put(MultiUnitConstant.MULTI_UNIT_TEXT, groupMessage.getBaseName());
                        unitObj.put(MultiUnitConstant.VALUE, groupMessage.getBaseValue());
                    } else {
                        UnitItemPoJo unitItemPoJo = unitItemPoJoMap.get(Long.parseLong(unit));
                        unitObj.put(MultiUnitConstant.MULTI_UNIT_TEXT, unitItemPoJo.getText());
                        unitObj.put(MultiUnitConstant.VALUE, unitItemPoJo.getValue());
                        rate = unitItemPoJo.getRate();
                    }
                    resultJsonObject.put(SelectProductEnum.UNIT.getAttr(), unitObj);
                }
                if (StockConstant.MULTI_UNIT_TYPE_LIST.contains(businessType) && !(StockConstant.SERIAL_TYPE_LIST.contains(businessType) && Objects.equals(jsonObject.getInteger(ProductEnum.ENABLE_SERIAL_NUMBER.getSaasAttr()), 1))) {
                    resultJsonObject.put(ProductEnum.ENABLE_MULTI_UNIT.getSaasAttr(), 1);
                    JSONObject sellingMap = new JSONObject();
                    data.forEach((attr,attrValue)->{
                        if (ProductConstant.MULTI_PRICE_ATTR_LIST.contains(attr)) {
                            sellingMap.put(attr, attrValue);
                        }
                    });
                    if (Objects.equals(businessType, XbbRefTypeEnum.CONTRACT_OUTSTOCK.getCode()) || Objects.equals(businessType, XbbRefTypeEnum.WORK_ORDER_OUTSTOCK.getCode()) || Objects.equals(businessType, XbbRefTypeEnum.PRODUCTION_MATERIEL_OUTSTOCK.getCode())) {
                        if (Objects.nonNull(sellingMap.get(SelectProductEnum.COST.getAttr())) && Objects.nonNull(rate)) {
                            sellingMap.put(SelectProductEnum.COST.getAttr(), Arith.div(sellingMap.getDouble(SelectProductEnum.COST.getAttr()), rate));
                        }
                    }
                    resultJsonObject.put(ProductConstant.SELLING_PRICE_MAP, sellingMap);
                }
                resultJsonObject.put(ProductConstant.UNIT_RATE, unitItemPoJos);
                resultJsonObject.put(ProductConstant.TRANSFORM_UNIT_RATE, unitItemPoJos);
                if (data.containsKey(ProductConstant.PRODUCT_PRICE)) {
                    resultJsonObject.put(ProductConstant.PRICE, data.getJSONArray(ProductConstant.PRODUCT_PRICE));
                }

            } else {
                resultJsonObject.put(SelectProductEnum.UNIT.getAttr(), data.get(SelectProductEnum.UNIT.getAttr()));
            }
        }
    }


}
